#pragma once

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

const std::string null_file = "/dev/null";

void Daemon(const std::string &dir = "")
{
    // 守护进程不需要这些信号而终止进程，自己回处理，因此忽略这些信号，避免进程被杀死
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGSTOP, SIG_IGN);

    // 1.创建子进程，父进程退出子进程托孤给系统，让子进程守护进程化
    if (fork() > 0)
        exit(0);

    // 托孤后，我们就可以调用函数使自己变成独立会话，不受影响
    setsid();

    // 2.服务器启动后，我们可以自己定义该守护进程的工作路径，以方便获取我们的各种资源
    if (!dir.empty())
    {
        chdir(dir.c_str());
    }

    // 3.该进程没有终端，不需要键盘文件输入信息，因此我们因该丢弃0,1,2标准输入、输出、错误,但是直接关闭的话，代码中的调试信息就会报错
    // ，因此我们可以将其重定向/dev/null垃圾桶中
    int fd = open(null_file.c_str(), O_RDWR);
    if (fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }
}